package 线程通信;


public class 面包房 {

    //面包的库存：0~100
    private static int STORE;

    public static void main(String[] args) {
        //同时有2个生产者生产面包
        面包师傅 producer = new 面包师傅();
        for(int i=0; i<2; i++){
            new Thread(producer, "面包师傅-"+(i+1)).start();
        }
        消费者 consumer = new 消费者();
        for(int i=0; i<10; i++){
            new Thread(consumer, "消费者-"+(i+1)).start();
        }
    }

    //生产者/面包师傅：每次生产3个面包
    private static class 面包师傅 implements Runnable{

        private int num = 3;
        @Override
        public void run() {
            try {
                while (true) {//不停的生产
                    synchronized (面包房.class) {
                        while (num + STORE > 100) {//不满足生产条件：等待
                            面包房.class.wait();
                        }
                        //满足条件：生产
                        STORE += num;
                        //打印看看，让它等待一段时间(涉及synchronized优化的原理)
                        System.out.println(Thread.currentThread().getName() + " 生产了面包，库存：" + STORE);
                        Thread.sleep(500);

                        //通知wait等待的线程
                        //建议使用全部通知（极端情况，可能出现所有线程都等待的结果）
                        面包房.class.notifyAll();
                    }
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    //消费者：每次消费1个面包
    private static class 消费者 implements Runnable{

        private int num = 1;
        @Override
        public void run() {
            try {
                while (true) {//不停的消费
                    synchronized (面包房.class) {
                        while (STORE - num < 0) {//不满足消费条件：等待
                            面包房.class.wait();
                        }
                        //满足条件：生产
                        STORE -= num;
                        //打印看看，让它等待一段时间(涉及synchronized优化的原理)
                        System.out.println(Thread.currentThread().getName() + " 消费了面包，库存：" + STORE);
                        Thread.sleep(500);

                        //通知wait等待的线程
                        //建议使用全部通知（极端情况，可能出现所有线程都等待的结果）
                        面包房.class.notifyAll();
                    }
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}